<?php

/**
 * 路由分发器
 *
 * @author Jarhom <jarhom@gmail.com>
 * @modifier JianJian <silverd@sohu.com>
 * $Id: Dispatcher.php 168 2012-11-14 01:32:27Z silverd30@gmail.com $
 */

class Core_Dispatcher
{
    private static $_instance;
    public static function getInstance()
    {
        if (self::$_instance === null) {
            self::$_instance = new self();
        }
        return self::$_instance;
    }

    /**
     * 分发器
     *
     * @param array $dispatchInfo
        array(
            'controller' => 'Index',
            'action'     => 'index',
            'params' => array(
                'key1' => 'value1',
                'key2' => 'value2',
            ),
        );
     * @param string $controllerPath 如：Controller|Cli
     * @return void
     */
    public function dispatch($dispatchInfo, $controllerPath = 'Controller')
    {
        // 设置 controller + action
        $controller = $dispatchInfo['controller'];
        $action     = $dispatchInfo['action'];

        // 存储URL附加参数
        if (isset($dispatchInfo['params']) && $dispatchInfo['params']) {
            Core_Request_Http::getInstance()->setParams($dispatchInfo['params']);
        }

        $className = $controllerPath . '_' . $controller;
        $classPath = APP_PATH . 'Class' . DIRECTORY_SEPARATOR . str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';

        // 控制器不存在（报404错误）
        if (!is_file($classPath)) {
            throw new Core_Exception_404('Unable to find controller - ' . $classPath, 404);
        }

        require_once $classPath;

        if (!class_exists($className, false)) {
            throw new Core_Exception_404('Unable to find controller class - ' . $className, 404);
        }

        $controllerObj = new $className();

        // 控制器 preDispatch
        if (method_exists($controllerObj, 'preDispatch')) {
            $controllerObj->preDispatch();
        }

        // 正式分发
        $actionMethod = $action . 'Action';

        // 方法不存在（报404错误）
        if (!method_exists($controllerObj, $actionMethod)) {
            throw new Core_Exception_404('Unable to find action - ' . $className . '::' . $actionMethod, 404);
        }

        $result = $controllerObj->$actionMethod();

        // 控制器钩子 preResponse
        if (method_exists($controllerObj, 'preResponse')) {
            $controllerObj->preResponse();
        }

        // 插件调用：输出响应前
        Core_Plugin_Broker::invoke('preResponse');

        // 自动加载模板视图
        if (isset($controllerObj->autoRender) && $controllerObj->autoRender) {
            if ($result === null || $result) {

                // 模板文件
                $tpl = $controllerObj->getTpl()
                    ?: strtolower(str_replace('_', DS, $controller)) . DS . strtolower($action);

                // 模板文件完整路径
                $tplFilePath = template($tpl);

                if (!is_file($tplFilePath)) {
                    throw new Core_Exception_Fatal('Unable to find template - ' . $tplFilePath);
                }

                // 渲染视图、布局
                Core_View::getInstance()->layout($tpl);
            }
        }

        // 控制器 postDispatch
        if (method_exists($controllerObj, 'postDispatch')) {
            $controllerObj->postDispatch();
        }
    }
}